<template>
  <div class="search-container">
    <el-input
      v-model="searchText"
      :placeholder="disabled ? '请先选择城市' : placeholder"
      clearable
      @input="handleInput"
      @clear="handleClear"
      @focus="handleFocus"
      @blur="handleBlur"
      :disabled="disabled"
    />

    <!-- 搜索结果下拉框 -->
    <div
      v-show="showDropdown && searchResults.length > 0"
      class="search-dropdown"
    >
      <ul>
        <li
          v-for="(item, index) in searchResults"
          :key="index"
          @click="handleSelect(item.id, item.title)"
          :class="{ active: activeIndex === index }"
        >
          <div class="search-item">
            <span v-html="highlightText(item.title)"></span>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup name="SearchInputBox">
import { ref, computed, watch } from 'vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
  placeholder: {
    type: String,
    default: '请输入关键词搜索',
  },
  searchApi: {
    type: Function,
    required: true,
  },
  minLength: {
    type: Number,
    default: 1,
  },
  debounceTime: {
    type: Number,
    default: 700,
  },
  disabled: {
    type: Boolean,
    default: true,
  },
  searchData: {
    type: Array,
    default: () => [],
  },
});

const emit = defineEmits([
  'update:modelValue',
  'select',
  'clear',
  'latLongData',
  'input',
]);

const searchText = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value),
});

const searchResults = ref([]);
const showDropdown = ref(false);
const activeIndex = ref(-1);

// 添加一个标记，记录是否已经选择
const hasSelected = ref(false);

// 自定义防抖函数
const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

// 防抖处理搜索请求
const debouncedSearch = debounce(async (text) => {
  if (text.length >= props.minLength) {
    try {
      const results = await props.searchApi(text);
      searchResults.value = results;
      showDropdown.value = true;
    } catch (error) {
      console.error('搜索失败:', error);
      searchResults.value = [];
    }
  } else {
    searchResults.value = [];
    showDropdown.value = false;
  }
}, props.debounceTime);

// 使用 watch 监听 searchText 的变化
watch(
  () => searchText.value,
  (newValue) => {
    // 如果已经选择过，且值没有改变，则不显示下拉框
    if (hasSelected.value && searchText.value === newValue) {
      return;
    }

    // 如果值改变了，重置选择状态
    if (hasSelected.value) {
      hasSelected.value = false;
    }

    if (newValue && !props.disabled) {
      showDropdown.value = true;
      debouncedSearch(newValue);
    } else {
      searchResults.value = [];
      showDropdown.value = false;
    }
  }
);

// 修改处理输入函数
const handleInput = (value) => {
  try {
    emit('input', value);
  } catch (error) {
    console.error('输入处理失败:', error);
  }
};

// 处理清空
const handleClear = () => {
  searchText.value = '';
  searchResults.value = [];
  showDropdown.value = false;
  hasSelected.value = false; // 重置选择状态
  emit('clear');
};

// 修改选择处理函数
const handleSelect = (id, title) => {
  try {
    const selectedItem = searchResults.value.find((e) => e.id === id);
    if (!selectedItem) return;

    searchText.value = title;
    showDropdown.value = false;
    searchResults.value = [];
    hasSelected.value = true; // 标记已选择

    emit('select', selectedItem);
    emit('latLongData', [selectedItem]);
  } catch (error) {
    console.error('选择处理失败:', error);
  }
};

// 修改失焦处理函数
const handleBlur = () => {
  // 延迟关闭下拉框，确保可以点击选项
  setTimeout(() => {
    showDropdown.value = false;
    // 清空搜索结果，防止重复显示
    searchResults.value = [];
  }, 200);
};

// 修改处理焦点函数
const handleFocus = () => {
  // 如果已经选择过，不显示下拉框
  if (hasSelected.value) {
    return;
  }
  // 只有当有新的输入时才显示下拉框
  if (searchText.value && !searchResults.value.length) {
    debouncedSearch(searchText.value);
  }
};

// 高亮匹配文本
const highlightText = (text) => {
  if (!text || !searchText.value) return text || '';
  try {
    const regex = new RegExp(searchText.value, 'gi');
    return text.replace(
      regex,
      (match) => `<span class="highlight">${match}</span>`
    );
  } catch (error) {
    console.error('高亮文本处理失败:', error);
    return text;
  }
};

// 添加清空方法
const clearSearch = () => {
  searchText.value = '';
  searchResults.value = [];
  showDropdown.value = false;
  hasSelected.value = false; // 重置选择状态
};

// 暴露方法给父组件
defineExpose({
  clearSearch,
});
</script>

<style lang="scss" scoped>
.search-container {
  position: relative;
  width: 100%;
}

.search-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  max-height: 300px;
  overflow-y: auto;
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 1000;
  margin-top: 4px;

  ul {
    list-style: none;
    padding: 0;
    margin: 0;

    li {
      padding: 8px 12px;
      cursor: pointer;
      transition: background-color 0.3s;

      &:hover,
      &.active {
        background-color: #f5f7fa;
      }

      .search-item {
        display: flex;
        align-items: center;
      }
    }
  }
}

:deep(.highlight) {
  color: #409eff;
  font-weight: bold;
}

:deep(.el-input.is-disabled .el-input__wrapper) {
  background-color: var(
    --el-input-disabled-bg-color,
    var(--el-disabled-bg-color)
  );
  box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color))
    inset;
}
</style>
